﻿namespace OasisCiq.Xpil
{
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Xml;
    using System.Xml.Schema;
    using System.Xml.Serialization;
    using CommonTypes;
    using External;
    using Xml;
    using Xnl;
    using XS;

    /// <summary>
    /// A container for defining the unique characteristics of an organisation only
    /// Note at least organisation name required
    /// </summary>
    public class OrganisationDetailsType : 
        IValidityDateGroup, 
        IXLink, 
        IDataQualityGroup, 
        ILanguageCodeGroup,
        IExtendedAttributes,
        IXmlSerializable
    {
        private static readonly XmlQualifiedName XmlElementName =
            new XmlQualifiedName("OrganisationDetails", XmlNamespaces.Party);

        public virtual FreeTextLines FreeTextLines { get; set; }

        /// <summary>
        /// Note at least organisation name required
        /// </summary>
        public virtual ICollection<OrganisationNameType> OrganisationNames { get; set; }

        public virtual Addresses Addresses { get; set; }

        /// <summary>
        /// A container to define the accounts details of the 
        /// party such as utility account, financil accounts
        /// </summary>
        public virtual Accounts Accounts { get; set; }

        public virtual ContactNumbers ContactNumbers { get; set; }

        /// <summary>
        /// A container for identification document and cards of the 
        /// party that are unique to the party. e.g. license, 
        /// identification card, credit card, etc
        /// </summary>
        public virtual Documents Documents { get; set; }

        public virtual ElectronicAddressIdentifiers ElectronicAddressIdentifiers { get; set; }

        public virtual Events Events { get; set; }

        public virtual Identifiers Identifiers { get; set; }

        /// <summary>
        /// A container for memberships of party with other organisations 
        /// (e.g. industry groups) or social networks (clubs, association, etc)
        /// </summary>
        public virtual Memberships Memberships { get; set; }

        /// <summary>
        /// Relationships with other parties (persons or organisations, and the nature of relationship).
        /// Examples: 
        /// - For person: Contacts, blood relatives, friends, referees, customers, etc 
        /// - for Organisation: Subsidiary, Parent company, Branches, Divisions, Partners, etc
        /// </summary>
        public virtual Relationships Relationships { get; set; }

        /// <summary>
        /// Container for income / revenue information of the 
        /// party (salary/organisation revenue)
        /// </summary>
        public virtual Revenues Revenues { get; set; }

        public virtual Stocks Stocks { get; set; }

        public virtual Vehicles Vehicles { get; set; }

        public virtual OrganisationInfo OrganisationInfo { get; set; }

        /// <summary>
        /// Type of use of this data. e.g. data exchange, contact, update, create
        /// </summary>
        public virtual OrganisationDetailsUsageList Usage { get; set; }

        /// <summary>
        /// Status of the organisation details
        /// </summary>
        public virtual StatusList Status { get; set; }

        /// <summary>
        /// Could be start date, issue date, validity start date, etc
        /// </summary>
        public virtual XSDateTime DateValidFrom { get; set; }

        /// <summary>
        /// Could be end date, expiry date, validity end date, etc
        /// </summary>
        public virtual XSDateTime DateValidTo { get; set; }

        /// <summary>
        /// A primary key to reference Organisation Details.
        /// </summary>
        public virtual CTString OrganisationDetailsKey { get; set; }

        /// <summary>
        /// A foreign key to reference attribute Key of Organisation Details.
        /// </summary>
        public virtual CTString OrganisationDetailsKeyRef { get; set; }

        /// <summary>
        /// This attribute indicates what level of trust can be given to the parent element.
        /// Omit this attribute if the data quality is unknown. If the data quality is known,
        /// the value is "Valid, else "InValid"
        /// </summary>
        public virtual DataQualityTypeList DataQualityType { get; set; }

        /// <summary>
        /// Date the data quality is valid from
        /// </summary>
        public virtual XSDateTime ValidFrom { get; set; }

        /// <summary>
        /// Date the data quality is valid to
        /// </summary>
        public virtual XSDateTime ValidTo { get; set; }

        /// <summary>
        /// Human Language used. e.g. "en", "en-US", "en-AUS", etc
        /// </summary>
        public virtual XSLanguage LanguageCode { get; set; }

        public virtual NameValueCollection ExtendedAttributes { get; set; }

        #region IXmlSerializable implementation

        XmlSchema IXmlSerializable.GetSchema()
        {
            return null;
        }

        public virtual void ReadXml(XmlReader reader)
        {
            var wrapper = XmlUtilities.Wrap(reader);
            if (XmlUtilities.MoveToElement(wrapper, XmlElementName))
            {
                new XpilXmlReader(wrapper).ReadOrganisationDetails(
                    this,
                    XmlElementName.Name,
                    XmlElementName.Namespace);
            }
        }

        public virtual void WriteXml(XmlWriter writer)
        {
            new XpilXmlWriter(writer).WriteOrganisationDetails(this);
        }

        #endregion
    }
}
